#include "MyURB.h"

#define HEX(x) std::setw(2) << std::setfill(L'0') << std::hex << (int)(x) << std::dec


extern const char *PacketNames[];

const char *PipeTypes[] =
{
    "UsbdPipeTypeControl",
    "UsbdPipeTypeIsochronous",
    "UsbdPipeTypeBulk",
    "UsbdPipeTypeInterrupt"
};

void MY_URB::DeserializeHeader(unsigned char packType)
{
	packetName = PacketNames[packType];

    buffer.Read(&Hdr.Length,           sizeof(Hdr.Length));
    buffer.Read(&Hdr.Function,         sizeof(Hdr.Function));
    buffer.Read(&Hdr.Status,           sizeof(Hdr.Status));
    buffer.Read(&Hdr.UsbdDeviceHandle, sizeof(Hdr.UsbdDeviceHandle));
    buffer.Read(&Hdr.UsbdFlags,        sizeof(Hdr.UsbdFlags));
    buffer.Read(&isCompleted, sizeof(isCompleted));
    if (isCompleted)
        direction = "UP";
    else
        direction = "DOWN";
}

std::wstring MY_URB_WITH_TRANSFER_BUFFER::PrintTransferFlags(unsigned long TransferFlags)
{
    std::wstringstream tmp;
    tmp << std::hex;
    tmp << L"<tr><td><b>TransferFlags:</b></td>" << L"<td> 0x" << TransferFlags << L" (";
    if ((bool)(TransferFlags & 1))
    {
        tmp << L"USBD_TRANSFER_DIRECTION_IN";
    }
    else
    {
        tmp << L"USBD_TRANSFER_DIRECTION_OUT";
    }
    if ((bool)(TransferFlags & 0x2))
    {
        tmp << L" | USBD_SHORT_TRANSFER_OK";
    }
    tmp << L")</td></tr>";
    return tmp.str();
}

std::wstring MY_URB_WITH_TRANSFER_BUFFER::PrintTransferBuffer()
{
    std::wstringstream tmp;
    unsigned i;  
    tmp << L"<tr><td><b>TransferBufferLength:</b></td><td> " << TransferBufferLength << L"</td></tr>";
    if (thereIsAnMDL)
    {
        tmp << L"<br><tr><td><b>TransferBufferMDL:</b></td><td>";
        for (i=0; i<TransferBufferLength; ++i)
            tmp << HEX(TransferBufferMDL[i]) << ' ';
        return tmp.str();
    }
    tmp << L"<br><tr><td><b>TransferBuffer:</b></td><td>";
    for (i=0; i<TransferBufferLength; ++i)
        tmp << HEX(TransferBuffer[i]) << ' ';
    return tmp.str();
}

void MY_URB_WITH_TRANSFER_BUFFER::DeserializeTransferBuffer()
{
    buffer.Read(&thereIsAnMDL, sizeof(thereIsAnMDL));
    buffer.Read(&TransferBufferLength, sizeof(TransferBufferLength));
    if (thereIsAnMDL)
    {
        TransferBufferMDL = new unsigned char[TransferBufferLength];
        buffer.Read(TransferBufferMDL, TransferBufferLength);
        return;
    }
    TransferBuffer = new unsigned char[TransferBufferLength];
    buffer.Read(TransferBuffer, TransferBufferLength);
}

std::wstring MY_URB_SELECT_INTERFACE::GetDetailedInfo()
{
    std::wstringstream tmp;
    unsigned i;
    tmp << std::hex;
    tmp << L"<tr><td><b>ConfigurationHandle:</b></td><td>0x"       << ConfigurationHandle << L"</td></tr>";
	
	tmp << L"<tr><td>Interface.Length:</td><td>"            <<(int)Interface.Length << L"</td></tr>";
	tmp << L"<tr><td>Interface.InterfaceNumber:</td><td>0x" << HEX(Interface.InterfaceNumber) << L"</td></tr>";
	tmp << L"<tr><td>Interface.AlternateSetting:</td><td>0x"<< HEX(Interface.AlternateSetting) << L"</td></tr>";
	tmp << L"<tr><td>Interface.Class:</td><td>0x"           << HEX(Interface.Class) << L"</td></tr>";
	tmp << L"<tr><td>Interface.SubClass:</td><td>0x"        << HEX(Interface.SubClass) << L"</td></tr>";
	tmp << L"<tr><td>Interface.Protocol:</td><td>0x"        << HEX(Interface.Protocol) << L"</td></tr>";
	tmp << L"<tr><td>Interface.InterfaceHandle:</td><td>0x" << std::hex << Interface.InterfaceHandle << L"</td></tr>";
	tmp << L"<tr><td>Interface.NumberOfPipes:</td><td>"     << Interface.NumberOfPipes << L"</td></tr><br>";

	//std::vector<MY_USBD_PIPE_INFORMATION> Pipes = Interface.Pipes;
    for (i=0; i<Interface.NumberOfPipes; ++i)
    {
		tmp << L"<tr><td>Pipes["<<i<<"].MaximumPacketSize<td>"    << (int)Interface.Pipes[i].MaximumPacketSize << L"</td></tr>";
		tmp << L"<tr><td>Pipes["<<i<<"].EndpointAddress<td>0x" <<     HEX(Interface.Pipes[i].EndpointAddress) << L"</td></tr>";
		tmp << L"<tr><td>Pipes["<<i<<"].Interval<td>0x" <<            HEX(Interface.Pipes[i].Interval) << L"</td></tr>";
		tmp << L"<tr><td>Pipes["<<i<<"].PipeType<td>" <<        PipeTypes[Interface.Pipes[i].PipeType] << L"</td></tr>";
		tmp << L"<tr><td>Pipes["<<i<<"].PipeHandle<td>0x"            <<   Interface.Pipes[i].PipeHandle << L"</td></tr>";
		tmp << L"<tr><td>Pipes["<<i<<"].MaximumTransferSize" <<  "<td>" <<Interface.Pipes[i].MaximumTransferSize << L"</td></tr>";
		tmp << L"<tr><td>Pipes["<<i<<"].PipeFlags" <<            "<td>" <<Interface.Pipes[i].PipeFlags << L"</td></tr><br>";
    }
    return tmp.str();
}

void MY_URB_SELECT_INTERFACE::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    unsigned i;
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&ConfigurationHandle, sizeof(ConfigurationHandle));

    buffer.Read(&Interface.Length,           sizeof(Interface.Length));
    buffer.Read(&Interface.InterfaceNumber,  sizeof(Interface.InterfaceNumber));
    buffer.Read(&Interface.AlternateSetting, sizeof(Interface.AlternateSetting));
    buffer.Read(&Interface.Class,            sizeof(Interface.Class));
    buffer.Read(&Interface.SubClass,         sizeof(Interface.SubClass));
    buffer.Read(&Interface.Protocol,         sizeof(Interface.Protocol));
    buffer.Read(&Interface.InterfaceHandle,  sizeof(Interface.InterfaceHandle));
    buffer.Read(&Interface.NumberOfPipes,    sizeof(Interface.NumberOfPipes));

	MY_USBD_PIPE_INFORMATION tmpPipe;
    for (i=0; i<Interface.NumberOfPipes; ++i)
    {
        buffer.Read(&tmpPipe.MaximumPacketSize,   sizeof(tmpPipe.MaximumPacketSize));
        buffer.Read(&tmpPipe.EndpointAddress,     sizeof(tmpPipe.EndpointAddress));
        buffer.Read(&tmpPipe.Interval,            sizeof(tmpPipe.Interval));
        buffer.Read(&tmpPipe.PipeType,            sizeof(tmpPipe.PipeType));
        buffer.Read(&tmpPipe.PipeHandle,          sizeof(tmpPipe.PipeHandle));
        buffer.Read(&tmpPipe.MaximumTransferSize, sizeof(tmpPipe.MaximumTransferSize));
        buffer.Read(&tmpPipe.PipeFlags,           sizeof(tmpPipe.PipeFlags));
		Interface.Pipes.push_back(tmpPipe);
    }
}

MY_URB_SELECT_CONFIGURATION::MY_URB_SELECT_CONFIGURATION()
{
    ConfigurationDescriptor.bLength             = 0;
    ConfigurationDescriptor.bDescriptorType     = 0;
    ConfigurationDescriptor.wTotalLength        = 0;
    ConfigurationDescriptor.bNumInterfaces      = 0;
    ConfigurationDescriptor.bConfigurationValue = 0;
    ConfigurationDescriptor.iConfiguration      = 0;
    ConfigurationDescriptor.bmAttributes        = 0;
    ConfigurationDescriptor.MaxPower            = 0;
}

std::wstring MY_URB_SELECT_CONFIGURATION::GetDetailedInfo()
{
    unsigned i, j;
    std::wstringstream tmp;
    tmp << std::hex;
    tmp << L"<tr><td><b>ConfigurationHandle:</b></td><td>0x" << ConfigurationHandle << L"</td></tr>";
    if (!bConfigurationDescriptor)
    {
        return tmp.str();
    }
    MY_USB_CONFIGURATION_DESCRIPTOR *pC = &ConfigurationDescriptor;
    tmp << L"<br><tr><td>ConfigurationDescriptor.bLength:</td><td>0x"         << HEX(pC->bLength) << L"</td></tr>";
    tmp << L"<tr><td>ConfigurationDescriptor.bDescriptorType:</td><td>0x"     << HEX(pC->bDescriptorType) << L"</td></tr>";
    tmp << L"<tr><td>ConfigurationDescriptor.wTotalLength:</td><td>"          <<(int)pC->wTotalLength << L"</td></tr>";
    tmp << L"<tr><td>ConfigurationDescriptor.bNumInterfaces:</td><td>"        << HEX(pC->bNumInterfaces) << L"</td></tr>";
    tmp << L"<tr><td>ConfigurationDescriptor.bConfigurationValue:</td><td>0x" << HEX(pC->bConfigurationValue) << L"</td></tr>";
    tmp << L"<tr><td>ConfigurationDescriptor.iConfiguration:</td><td>0x"      << HEX(pC->iConfiguration) << L"</td></tr>";
    tmp << L"<tr><td>ConfigurationDescriptor.bmAttributes:</td><td>0x"        << HEX(pC->bmAttributes) << L"</td></tr>";
    tmp << L"<tr><td>ConfigurationDescriptor.MaxPower:</td><td>0x"            << HEX(pC->MaxPower) << L"</td></tr>";

    for (i=0; i<pC->bNumInterfaces; ++i)
    {
        tmp << L"<br><tr><td>Interface["<<i<<"].Length:</td><td>"        <<(int)Interface[i].Length << L"</td></tr>";
        tmp << L"<tr><td>Interface["<<i<<"].InterfaceNumber:</td><td>0x" << HEX(Interface[i].InterfaceNumber) << L"</td></tr>";
        tmp << L"<tr><td>Interface["<<i<<"].AlternateSetting:</td><td>0x"<< HEX(Interface[i].AlternateSetting) << L"</td></tr>";
        tmp << L"<tr><td>Interface["<<i<<"].Class:</td><td>0x"           << HEX(Interface[i].Class) << L"</td></tr>";
        tmp << L"<tr><td>Interface["<<i<<"].SubClass:</td><td>0x"        << HEX(Interface[i].SubClass) << L"</td></tr>";
        tmp << L"<tr><td>Interface["<<i<<"].Protocol:</td><td>0x"        << HEX(Interface[i].Protocol) << L"</td></tr>";
		tmp << L"<tr><td>Interface["<<i<<"].InterfaceHandle:</td><td>0x" << std::hex << Interface[i].InterfaceHandle << L"</td></tr>";
        tmp << L"<tr><td>Interface["<<i<<"].NumberOfPipes:</td><td> "        << Interface[i].NumberOfPipes << L"</td></tr>";

        for (j=0; j<Interface[i].NumberOfPipes; ++j)
        {
            tmp << L"<br><tr><td>Pipes["<<j<<"].MaximumPacketSize<td>" <<     (int)Interface[i].Pipes[j].MaximumPacketSize << L"</td></tr>";
            tmp << L"<tr><td>Pipes["<<j<<"].EndpointAddress" <<"<td>0x" <<HEX(Interface[i].Pipes[j].EndpointAddress) << L"</td></tr>";
            tmp << L"<tr><td>Pipes["<<j<<"].Interval" <<       "<td>0x" <<HEX(Interface[i].Pipes[j].Interval) << L"</td></tr>";
            tmp << L"<tr><td>Pipes["<<j<<"].PipeType<td>"         <<PipeTypes[Interface[i].Pipes[j].PipeType] << L"</td></tr>";
			tmp << L"<tr><td>Pipes["<<j<<"].PipeHandle<td>0x" << std::hex <<  Interface[i].Pipes[j].PipeHandle << L"</td></tr>";
            tmp << L"<tr><td>Pipes["<<j<<"].MaximumTransferSize" <<  "<td>" <<Interface[i].Pipes[j].MaximumTransferSize << L"</td></tr>";
            tmp << L"<tr><td>Pipes["<<j<<"].PipeFlags" <<            "<td>" <<Interface[i].Pipes[j].PipeFlags << L"</td></tr>";
        }
    }
    return tmp.str();
}

void MY_URB_SELECT_CONFIGURATION::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    unsigned i, j;
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&bConfigurationDescriptor, sizeof(bConfigurationDescriptor));
    if(!bConfigurationDescriptor)
    {
        buffer.Read(&ConfigurationHandle, sizeof(ConfigurationHandle));
        return;
    }
    
    MY_USB_CONFIGURATION_DESCRIPTOR *pConfD = &ConfigurationDescriptor;
    buffer.Read(&pConfD->bLength,             sizeof(pConfD->bLength));
    buffer.Read(&pConfD->bDescriptorType,     sizeof(pConfD->bDescriptorType));
    buffer.Read(&pConfD->wTotalLength,        sizeof(pConfD->wTotalLength));
    buffer.Read(&pConfD->bNumInterfaces,      sizeof(pConfD->bNumInterfaces));
    buffer.Read(&pConfD->bConfigurationValue, sizeof(pConfD->bConfigurationValue));
    buffer.Read(&pConfD->iConfiguration,      sizeof(pConfD->iConfiguration));
    buffer.Read(&pConfD->bmAttributes,        sizeof(pConfD->bmAttributes));
    buffer.Read(&pConfD->MaxPower,            sizeof(pConfD->MaxPower));

    MY_USBD_INTERFACE_INFORMATION tmpInterface;

    for (i=0; i<pConfD->bNumInterfaces; ++i)
    {
        buffer.Read(&tmpInterface.Length,           sizeof(tmpInterface.Length));
        buffer.Read(&tmpInterface.InterfaceNumber,  sizeof(tmpInterface.InterfaceNumber));
        buffer.Read(&tmpInterface.AlternateSetting, sizeof(tmpInterface.AlternateSetting));
        buffer.Read(&tmpInterface.Class,            sizeof(tmpInterface.Class));
        buffer.Read(&tmpInterface.SubClass,         sizeof(tmpInterface.SubClass));
        buffer.Read(&tmpInterface.Protocol,         sizeof(tmpInterface.Protocol));
        buffer.Read(&tmpInterface.InterfaceHandle,  sizeof(tmpInterface.InterfaceHandle));
        buffer.Read(&tmpInterface.NumberOfPipes,    sizeof(tmpInterface.NumberOfPipes));

		MY_USBD_PIPE_INFORMATION tmpPipe;

        for (j=0; j<tmpInterface.NumberOfPipes; ++j)
        {
            buffer.Read(&tmpPipe.MaximumPacketSize,   sizeof(tmpPipe.MaximumPacketSize));
            buffer.Read(&tmpPipe.EndpointAddress,     sizeof(tmpPipe.EndpointAddress));
            buffer.Read(&tmpPipe.Interval,            sizeof(tmpPipe.Interval));
            buffer.Read(&tmpPipe.PipeType,            sizeof(tmpPipe.PipeType));
            buffer.Read(&tmpPipe.PipeHandle,          sizeof(tmpPipe.PipeHandle));
            buffer.Read(&tmpPipe.MaximumTransferSize, sizeof(tmpPipe.MaximumTransferSize));
            buffer.Read(&tmpPipe.PipeFlags,           sizeof(tmpPipe.PipeFlags));
			tmpInterface.Pipes.push_back(tmpPipe);
        }
		Interface.push_back(tmpInterface);
    }
    buffer.Read(&ConfigurationHandle, sizeof(ConfigurationHandle));
}

std::wstring MY_URB_PIPE_REQUEST::GetDetailedInfo()
{
    std::wstringstream tmp;
    tmp << L"<tr><td><b>PipeHandle:</b></td><td>0x" << std::hex << PipeHandle << L"</td></tr>";
    return tmp.str();
}

void MY_URB_PIPE_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&PipeHandle, sizeof(PipeHandle));
}

std::wstring MY_URB_GET_CURRENT_FRAME_NUMBER::GetDetailedInfo()
{
    std::wstringstream tmp;
    tmp << L"<tr><td><b>FrameNumber:</b></td><td>0x" << FrameNumber << L"</td></tr>";
    return tmp.str();
}

void MY_URB_GET_CURRENT_FRAME_NUMBER::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&FrameNumber, sizeof(FrameNumber));
}

std::wstring MY_URB_CONTROL_TRANSFER::GetDetailedInfo()
{
    std::wstringstream tmp;
    wchar_t wTmp, *pwTmp;
	unsigned char chTmp, c;

    tmp << L"<tr><td><b>PipeHandle:</b></td><td>0x" << std::hex << PipeHandle << L"</td></tr>";


    tmp << L"<tr><td><b>Setup Packet:</b></td></tr>";
    chTmp = SetupPacket[0];
    tmp << L"<tr><td>&nbsp;&nbsp;&nbsp;Data Phase Transfer Direction:</td><td>";
    if ((bool)(chTmp & 128))
        tmp << L"Device to Host</td></tr>";
    else
        tmp << L"Host to Device</td></tr>";
    tmp << L"<tr><td>&nbsp;&nbsp;&nbsp;Type:</td><td>";
    c = (chTmp & 96);
    switch (c)
    {
        case 0:  {tmp << L"Standard";}break;
        case 32: {tmp << L"Class";}break;
        case 64: {tmp << L"Vendor";}break;
        case 96: {tmp << L"Reserved";}break;
    }
    c = (chTmp & 31);
    tmp << L"</td></tr><tr><td>&nbsp;&nbsp;&nbsp;Recipient:</td><td>";
    switch (c)
    {
        case 0: {tmp << L"Device";}break;
        case 1: {tmp << L"Interface";}break;
        case 2: {tmp << L"Endpoint";}break;
        case 3: {tmp << L"Other";}break;
        default:{tmp << L"Reserved";}break;
    }
    chTmp = SetupPacket[1];
    tmp << L"</td></tr><tr><td>&nbsp;&nbsp;&nbsp;bRequest:</td><td>0x"<< HEX(chTmp) << L"</td></tr>";
    pwTmp = (wchar_t*)&SetupPacket[2];
    wTmp = *pwTmp;
    tmp << L"<tr><td>&nbsp;&nbsp;&nbsp;wValue:<</td><td>" << (int)(wTmp) << L"</td></tr>";
    pwTmp = (wchar_t*)&SetupPacket[4];
    wTmp = *pwTmp;
    tmp << L"<tr><td>&nbsp;&nbsp;&nbsp;wIndex:<</td><td>" << (int)(wTmp) << L"</td></tr>";
    pwTmp = (wchar_t*)&SetupPacket[6];
    wTmp = *pwTmp;
    tmp << L"<tr><td>&nbsp;&nbsp;&nbsp;wLength:</td><td>" << (int)(wTmp) << L"</td></tr>";


    tmp << PrintTransferFlags(TransferFlags);

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);
    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
       tmp << PrintTransferBuffer();
    }
    return tmp.str();
}

void MY_URB_CONTROL_TRANSFER::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&PipeHandle,    sizeof(PipeHandle));
    buffer.Read(&TransferFlags, sizeof(TransferFlags));

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);

    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
        DeserializeTransferBuffer();
    }
    buffer.Read(SetupPacket, sizeof(SetupPacket));
}

std::wstring MY_URB_CONTROL_TRANSFER_EX::GetDetailedInfo()
{
    std::wstringstream tmp;
    wchar_t wTmp, *pwTmp;
	unsigned char chTmp, c;

    tmp << L"<tr><td><b>PipeHandle:</b></td><td>0x" << std::hex << PipeHandle << L"</td></tr>";
    tmp << L"<tr><td><b>Timeout:</b></td><td>0x" << Timeout << L"</td></tr>";

	tmp << L"<tr><td><b>Setup Packet:</b></td></tr>";
	chTmp = SetupPacket[0];
	tmp << L"<tr><td>&nbsp;&nbsp;&nbsp;Data Phase Transfer Direction:</td><td>";
	if ((bool)(chTmp & 128))
		tmp << L"Device to Host</td></tr>";
	else
		tmp << L"Host to Device</td></tr>";
	tmp << L"<tr><td>&nbsp;&nbsp;&nbsp;Type:</td><td>";
	c = (chTmp & 96);
	switch (c)
	{
	case 0:  {tmp << L"Standard";}break;
	case 32: {tmp << L"Class";}break;
	case 64: {tmp << L"Vendor";}break;
	case 96: {tmp << L"Reserved";}break;
	}
	c = (chTmp & 31);
	tmp << L"</td></tr><tr><td>&nbsp;&nbsp;&nbsp;Recipient:</td><td>";
	switch (c)
	{
	case 0: {tmp << L"Device";}break;
	case 1: {tmp << L"Interface";}break;
	case 2: {tmp << L"Endpoint";}break;
	case 3: {tmp << L"Other";}break;
	default:{tmp << L"Reserved";}break;
	}
	chTmp = SetupPacket[1];
	tmp << L"</td></tr><tr><td>&nbsp;&nbsp;&nbsp;bRequest:</td><td>0x"<< HEX(chTmp) << L"</td></tr>";
	pwTmp = (wchar_t*)&SetupPacket[2];
	wTmp = *pwTmp;
	tmp << L"<tr><td>&nbsp;&nbsp;&nbsp;wValue:<</td><td>" << (int)(wTmp) << L"</td></tr>";
	pwTmp = (wchar_t*)&SetupPacket[4];
	wTmp = *pwTmp;
	tmp << L"<tr><td>&nbsp;&nbsp;&nbsp;wIndex:<</td><td>" << (int)(wTmp) << L"</td></tr>";
	pwTmp = (wchar_t*)&SetupPacket[6];
	wTmp = *pwTmp;
	tmp << L"<tr><td>&nbsp;&nbsp;&nbsp;wLength:</td><td>" << (int)(wTmp) << L"</td></tr>";



    tmp << PrintTransferFlags(TransferFlags);

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);
    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
       tmp << PrintTransferBuffer();
    }
    return tmp.str();
}

void MY_URB_CONTROL_TRANSFER_EX::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&PipeHandle,    sizeof(PipeHandle));
    buffer.Read(&TransferFlags, sizeof(TransferFlags));

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);

    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
        DeserializeTransferBuffer();
    }
    buffer.Read(&Timeout,    sizeof(Timeout));
    buffer.Read(SetupPacket, sizeof(SetupPacket));
}

std::wstring MY_URB_BULK_OR_INTERRUPT_TRANSFER::GetDetailedInfo()
{
    std::wstringstream tmp;
    tmp << L"<tr><td><b>PipeHandle:</b></td><td>0x" << std::hex << PipeHandle << L"</td></tr>";
    tmp << PrintTransferFlags(TransferFlags);

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);
    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
       tmp << PrintTransferBuffer();
    }
    return tmp.str();
}

void MY_URB_BULK_OR_INTERRUPT_TRANSFER::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);
    
    buffer.Read(&PipeHandle,    sizeof(PipeHandle));
    buffer.Read(&TransferFlags, sizeof(TransferFlags));

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);

    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
        DeserializeTransferBuffer();
    }
}

std::wstring MY_URB_ISOCH_TRANSFER::GetDetailedInfo()
{
    std::wstringstream tmp;
    unsigned i;
    tmp << L"<tr><td><b>PipeHandle:</b></td><td>0x" << std::hex << PipeHandle << L"</td></tr>";
    tmp << L"<tr><td><b>StartFrame:</b></td><td>" << std::dec << StartFrame << L"</td></tr>";
    tmp << L"<tr><td><b>NumberOfPackets:</b></td><td>" << NumberOfPackets << L"</td></tr>";
    tmp << L"<tr><td><b>PipeHandle:</b></td><td>" << ErrorCount << L"</td></tr><br>";
    tmp << PrintTransferFlags(TransferFlags);

    for (i=0; i<NumberOfPackets; ++i)
    {
        tmp << L"<tr><td><b>IsoPacket["<<i<<"].</b></td><td>Offset:" << IsoPacket[i].Offset;
        tmp << L"<tr><td><b>IsoPacket["<<i<<"].</b></td><td>Length:" << IsoPacket[i].Length;
        tmp << L"<tr><td><b>IsoPacket["<<i<<"].</b></td><td>Status:" << IsoPacket[i].Status;
    }

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);
    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
       tmp << PrintTransferBuffer();
    }

    return tmp.str();
}

void MY_URB_ISOCH_TRANSFER::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    unsigned i;
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&PipeHandle,    sizeof(PipeHandle));
    buffer.Read(&TransferFlags, sizeof(TransferFlags));

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);

    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
        DeserializeTransferBuffer();
    }

    buffer.Read(&StartFrame,      sizeof(StartFrame));
    buffer.Read(&NumberOfPackets, sizeof(NumberOfPackets));
    buffer.Read(&ErrorCount,      sizeof(ErrorCount));

	MY_USBD_ISO_PACKET_DESCRIPTOR tmpIsoPacket;

    for (i=0; i<NumberOfPackets; ++i)
    {
        buffer.Read(&tmpIsoPacket.Offset, sizeof(tmpIsoPacket.Offset));
        buffer.Read(&tmpIsoPacket.Length, sizeof(tmpIsoPacket.Length));
        buffer.Read(&tmpIsoPacket.Status, sizeof(tmpIsoPacket.Status));
		IsoPacket.push_back(tmpIsoPacket);
    }
}

std::wstring MY_URB_CONTROL_DESCRIPTOR_REQUEST::GetDetailedInfo()
{
    std::wstringstream tmp;
    tmp << L"<tr><td><b>Index:</b></td><td>0x" << HEX(Index) << L"</td></tr>";
    tmp << L"<tr><td><b>DescriptorType:</b></td><td>0x" << HEX(DescriptorType);
    switch (DescriptorType)
    {
        case 1: {tmp << L" (USB_DEVICE_DESCRIPTOR_TYPE)";} break;
        case 2: {tmp << L" (USB_CONFIGURATION_DESCRIPTOR_TYPE)";} break;
        case 3: {tmp << L" (USB_STRING_DESCRIPTOR_TYPE)";} break;
        default:{tmp << L" (UNKNOWN)";} break;
    }
    tmp << L"<tr><td><b>LanguageId:</b></td><td>0x" << HEX(LanguageId);
    if (thereIsBuffer)
    {
        tmp << PrintTransferBuffer();
    }
    return tmp.str();
}

void MY_URB_CONTROL_DESCRIPTOR_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&thereIsBuffer, sizeof(thereIsBuffer));
    if (thereIsBuffer)
        DeserializeTransferBuffer();

    buffer.Read(&Index,          sizeof(Index));
    buffer.Read(&DescriptorType, sizeof(DescriptorType));
    buffer.Read(&LanguageId,     sizeof(LanguageId));
}

std::wstring MY_URB_CONTROL_GET_STATUS_REQUEST::GetDetailedInfo()
{
    std::wstringstream tmp;
    tmp << L"<tr><td><b>Index:</b></td><td>0x" << std::hex << (int)Index << L"</td></tr>";
    if (isCompleted)
    {
        tmp << PrintTransferBuffer();
    }
    return tmp.str();
}

void MY_URB_CONTROL_GET_STATUS_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);
    if (isCompleted)
    {
        DeserializeTransferBuffer();
    }

    buffer.Read(&Index, sizeof(Index));
}

std::wstring MY_URB_CONTROL_FEATURE_REQUEST::GetDetailedInfo()
{
    std::wstringstream tmp;
    tmp << L"<tr><td><b>FeatureSelector:</b></td><td>0x" << std::hex << (int)FeatureSelector << L"</td></tr>";
    tmp << L"<tr><td><b>Index:</b></td><td>0x" << std::hex << (int)Index << L"</td></tr>";
    return tmp.str();
}

void MY_URB_CONTROL_FEATURE_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&FeatureSelector, sizeof(FeatureSelector));
    buffer.Read(&Index,           sizeof(Index));
}

std::wstring MY_URB_CONTROL_VENDOR_OR_CLASS_REQUEST::GetDetailedInfo()
{
    std::wstringstream tmp;
    tmp << L"<tr><td><b>RequestTypeReservedBits:</b></td><td>0x" << HEX(RequestTypeReservedBits) << L"</td></tr>";
    tmp << L"<tr><td><b>Request:</b></td><td>0x" << std::hex << HEX(Request) << L"</td></tr>";
    tmp << L"<tr><td><b>Value:</b></td><td>" << std::dec << (int)Value << L"</td></tr>";
    tmp << L"<tr><td><b>Index:</b></td><td>" << (int)Index << L"</td></tr>";

    tmp << PrintTransferFlags(TransferFlags);

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);
    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
       tmp << PrintTransferBuffer();
    }
    return tmp.str();
}

void MY_URB_CONTROL_VENDOR_OR_CLASS_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&TransferFlags,	sizeof(TransferFlags));

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);
    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
        DeserializeTransferBuffer();
    }
    buffer.Read(&RequestTypeReservedBits, sizeof(RequestTypeReservedBits));

    buffer.Read(&Request, sizeof(Request));
    buffer.Read(&Value,   sizeof(Value));
    buffer.Read(&Index,   sizeof(Index));
}

std::wstring MY_URB_CONTROL_GET_INTERFACE_REQUEST::GetDetailedInfo()
{
    std::wstringstream tmp;
    tmp << L"<tr><td><b>Interface:</b></td><td>0x" << (int)Interface << L"</td></tr>";
    if (isCompleted)
    {
        tmp << PrintTransferBuffer();
    }
    return tmp.str();
}

void MY_URB_CONTROL_GET_INTERFACE_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    if (isCompleted)
    {
        DeserializeTransferBuffer();
    }

    buffer.Read(&Interface, sizeof(Interface));
}

std::wstring MY_URB_CONTROL_GET_CONFIGURATION_REQUEST::GetDetailedInfo()
{
    std::wstringstream tmp;
    if (isCompleted)
    {
        tmp << PrintTransferBuffer();
    }
    return tmp.str();
}

void MY_URB_CONTROL_GET_CONFIGURATION_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);
    if (isCompleted)
    {
        DeserializeTransferBuffer();
    }
}

std::wstring MY_URB_OS_FEATURE_DESCRIPTOR_REQUEST::GetDetailedInfo()
{
    std::wstringstream tmp;
    tmp << L"<tr><td><b>Recipient:</b></td><td>0x"       << HEX(Recipient) << L"</td></tr>";
    tmp << L"<tr><td><b>InterfaceNumber:</b></td><td>0x" << HEX(InterfaceNumber) << L"</td></tr>";
    tmp << L"<tr><td><b>MS_PageIndex:</b></td><td>0x"    << HEX(MS_PageIndex) << L"</td></tr>";
    tmp << L"<tr><td><b>MS_FeatureDescriptorIndex:</b></td><td>" << (int)MS_FeatureDescriptorIndex << L"</td></tr>";
    if (isCompleted)
    {
        tmp << PrintTransferBuffer();
    }
    return tmp.str();
}

void MY_URB_OS_FEATURE_DESCRIPTOR_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);
    if (isCompleted)
    {
        DeserializeTransferBuffer();
    }

    buffer.Read(&Recipient,                 sizeof(Recipient));
    buffer.Read(&InterfaceNumber,           sizeof(InterfaceNumber));
    buffer.Read(&MS_PageIndex,              sizeof(MS_PageIndex));
    buffer.Read(&MS_FeatureDescriptorIndex, sizeof(MS_FeatureDescriptorIndex));
}
